package org.apache.ocean.main.search;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.commons.lang.StringUtils;
import org.apache.lucene.index.Term;
import org.apache.ocean.main.IndexSchema;
import org.apache.ocean.main.http.HttpParameters;
import org.apache.ocean.main.util.CElement;
import org.apache.ocean.main.util.XMLUtil;
import org.jdom.Element;

/**
 * 
 * @author jasonr
 */
public class TermFrequencies extends HashMap<Term, AtomicInteger> implements CElement {
	private int maxDoc;
	private long snapshotId;
	private IndexSchema.Category schemaCategory;
	private Long elapsed;
	
	public TermFrequencies(int maxDoc, long snapshotId, IndexSchema.Category schemaCategory) {
		this.maxDoc = maxDoc;
		this.snapshotId = snapshotId;
		this.schemaCategory = schemaCategory;
	}
	
	public TermFrequencies(IndexSchema.Category schemaCategory) {
		this.schemaCategory = schemaCategory;
	}
	
	public TermFrequencies(Element root, IndexSchema.Category schemaCategory) {
		maxDoc = XMLUtil.getAttributeInteger("maxdoc", root);
		snapshotId = XMLUtil.getAttributeLong("snapshotid", root);
		elapsed = XMLUtil.getAttributeLong("elapsed", root);
		for (Element element : XMLUtil.getChildren(root)) {
			String field = XMLUtil.getAttributeString("field", element);
			String text = XMLUtil.getAttributeString("text", element);
			Integer frequency = XMLUtil.getAttributeInteger("freq", element);
			String indexed = schemaCategory.readableToIndexed(field, text);
			Term term = new Term(field, indexed);
			add(term, frequency);
		}
	}
	
	public void setElapsed(Long elapsed) {
		this.elapsed = elapsed;
	}
	
	public Long getElapsed() {
		return elapsed;
	}
	
	public static TermFrequencies parse(HttpParameters parameters, IndexSchema.Category schemaCategory) {
		int maxDoc = parameters.getInt("maxdoc");
		long snapshotId = parameters.getLong("snapshotId");
		TermFrequencies termFrequencies = new TermFrequencies(maxDoc, snapshotId, schemaCategory);
		for (String value : parameters.getValues("termfreq")) {
			String[] split = StringUtils.split(value, ":");
			String field = split[0];
			String text = split[1];
			int frequency = Integer.parseInt(split[2]);
			String indexed = schemaCategory.readableToIndexed(field, text);
			Term term = new Term(field, indexed);
			termFrequencies.add(term, frequency);
		}
		return termFrequencies;
	}
		
	public void transferTo(HttpParameters parameters) {
		for (Map.Entry<Term,AtomicInteger> entry : entrySet()) {
			Term term = entry.getKey();
			String field = term.field();
			String text = schemaCategory.indexedToReadable(field, term.text());
			String value = field+":"+text+":"+entry.getValue();
			parameters.add("termfreq", value);
		}
	}
	
	public long getSnapshotId() {
		return snapshotId;
	}
	
	public void setMaxDoc(int maxDoc) {
		this.maxDoc = maxDoc;
	}
	
	public int getMaxDoc() {
		return maxDoc;
	}
	
	public Element toElement() {
		Element element = new Element("termfrequencies");
		XMLUtil.setAttribute("snapshotid", snapshotId, element);
		XMLUtil.setAttribute("maxdoc", maxDoc, element);
		
		return element;
	}
	
	public void add(Term term, int frequency) {
		AtomicInteger currentValue = get(term);
		if (currentValue == null) {
			put(term, new AtomicInteger(frequency));
		} else {
			currentValue.addAndGet(frequency);
		}
	}
}
